using System;
using CLELCore.Assembly.BlobStreams;
using CLELCore.Assembly.StreamTables;

namespace CLELCore.Assembly
{
	public static class TokenCompressor
	{
		public static byte [] CompressTypeDefOrRefToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.TYPEREF_TABLE)
			{
				flag = TokenDecompressor.TYPEDEFORREF_TYPEREF;
			}
			else if(type == StreamTable.TYPEDEF_TABLE)
			{
				flag = TokenDecompressor.TYPEDEFORREF_TYPEDEF;
			}
			else if(type == StreamTable.TYPESPEC_TABLE)
			{
				flag = TokenDecompressor.TYPEDEFORREF_TYPESPEC;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			row <<= 2;
			if(table_rows[StreamTable.TYPEDEF_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.TYPEREF_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.TYPESPEC_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX)
			{
				tok = new byte[2];

			}
			else
			{
				tok = new byte[4];
			}
			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressBlobTypeDefOrRefToken(Token token)
		{
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			int tok = 0;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.TYPEREF_TABLE)
			{
				flag = TokenDecompressor.TYPEDEFORREF_TYPEREF;
			}
			else if(type == StreamTable.TYPEDEF_TABLE)
			{
				flag = TokenDecompressor.TYPEDEFORREF_TYPEDEF;
			}
			else if(type == StreamTable.TYPESPEC_TABLE)
			{
				flag = TokenDecompressor.TYPEDEFORREF_TYPESPEC;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			
			row <<= 2;
			tok = row | flag;
			return Blob.CompressBlobValue(tok);
		}
		
		public static byte [] CompressHasConstantToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.FIELD_TABLE)
			{
				flag = TokenDecompressor.HASCONSTANT_FIELD;
			}
			else if(type == StreamTable.PARAM_TABLE)
			{
				flag = TokenDecompressor.HASCONSTANT_PARAM;
			}
			else if(type == StreamTable.PROPERTY_TABLE)
			{
				flag = TokenDecompressor.HASCONSTANT_PROPERTY;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			row <<= 2;
			if(table_rows[StreamTable.FIELD_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.PARAM_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.PROPERTY_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}
			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;
			
			return tok;
		}
		
		public static byte [] CompressHasCustomAttributeToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.METHODDEF_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_METHODDEF;
			}
			else if(type == StreamTable.FIELD_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_FIELD;
			}
			else if(type == StreamTable.TYPEREF_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_TYPEREF;
			}
			else if(type == StreamTable.TYPEDEF_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_TYPEDEF;
			}
			else if(type == StreamTable.PARAM_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_PARAM;
			}
			else if(type == StreamTable.INTERFACEIMPL_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_INTERFACEIMPL;
			}
			else if(type == StreamTable.MEMBERREF_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_MEMBERREF;
			}
			else if(type == StreamTable.MODULE_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_MODULE;
			}
			else if(type == StreamTable.DECLSECURITY_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_DECLSECURITY;
			}
			else if(type == StreamTable.PROPERTY_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_PROPERTY;
			}
			else if(type == StreamTable.EVENT_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_EVENT;
			}
			else if(type == StreamTable.STANDALONESIG_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_STANDALONESIG;
			}
			else if(type == StreamTable.MODULEREF_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_MODULEREF;
			}
			else if(type == StreamTable.TYPESPEC_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_TYPESPEC;
			}
			else if(type == StreamTable.ASSEMBLY_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_ASSEMBLY;
			}
			else if(type == StreamTable.ASSEMBLYREF_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_ASSEMBLYREF;
			}
			else if(type == StreamTable.FILE_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_FILE;
			}
			else if(type == StreamTable.EXPORTEDTYPE_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_EXPORTEDTYPE;
			}
			else if(type == StreamTable.MANIFESTRESOURCE_TABLE)
			{
				flag = TokenDecompressor.HASCUSTOMATTRIBUTE_MANIFESTRESOURCE;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			row <<= 5;
			if(table_rows[StreamTable.METHODDEF_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX && 
				table_rows[StreamTable.FIELD_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX && 
				table_rows[StreamTable.TYPEREF_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.TYPEDEF_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.PARAM_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.INTERFACEIMPL_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.MEMBERREF_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.MODULE_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.DECLSECURITY_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.PROPERTY_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.EVENT_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.STANDALONESIG_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.MODULEREF_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.TYPESPEC_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.ASSEMBLY_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.ASSEMBLYREF_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.FILE_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.EXPORTEDTYPE_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX &&
				table_rows[StreamTable.MANIFESTRESOURCE_TABLE] < TokenDecompressor.FIVE_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}
			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressCustomAttributeTypeToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.METHODDEF_TABLE)
			{
				flag = TokenDecompressor.CUSTOMATTRIBUTETYPE_METHODDEF;
			}
			else if(type == StreamTable.MEMBERREF_TABLE)
			{
				flag = TokenDecompressor.CUSTOMATTRIBUTETYPE_MEMBERREF;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			row <<= 3;
			if(table_rows[StreamTable.METHODDEF_TABLE] < TokenDecompressor.THREE_BIT_TAG_MAX && 
				table_rows[StreamTable.MEMBERREF_TABLE] < TokenDecompressor.THREE_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}
			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;
			
			return tok;
		}

		public static byte [] CompressHasDeclSecurityToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.TYPEDEF_TABLE)
			{
				flag = TokenDecompressor.HASDECLSECURITY_TYPEDEF;
			}
			else if(type == StreamTable.METHODDEF_TABLE)
			{
				flag = TokenDecompressor.HASDECLSECURITY_METHODDEF;
			}
			else if(type == StreamTable.ASSEMBLY_TABLE)
			{
				flag = TokenDecompressor.HASDECLSECURITY_ASSEMBLY;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			row <<= 2;
			if(table_rows[StreamTable.TYPEDEF_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.METHODDEF_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX &&
				table_rows[StreamTable.ASSEMBLY_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}
			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;
			
			return tok;
		}
		
		public static byte [] CompressMemberForwardedToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.FIELD_TABLE)
			{
				flag = TokenDecompressor.MEMBERFORWARDED_FIELD;
			}
			else if(type == StreamTable.METHODDEF_TABLE)
			{
				flag = TokenDecompressor.MEMBERFORWARDED_METHODDEF;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			row <<= 1;
			if(table_rows[StreamTable.FIELD_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX && 
				table_rows[StreamTable.METHODDEF_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}
			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressImplementationToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.FILE_TABLE)
			{
				flag = TokenDecompressor.IMPLEMENTATION_FILE;
			}
			else if(type == StreamTable.ASSEMBLYREF_TABLE)
			{
				flag = TokenDecompressor.IMPLEMENTATION_ASSEMBLYREF;
			}
			else if(type == StreamTable.EXPORTEDTYPE_TABLE)
			{
				flag = TokenDecompressor.IMPLEMENTATION_EXPORTEDTYPE;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			row <<= 2;
			if(table_rows[StreamTable.FILE_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.ASSEMBLYREF_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.EXPORTEDTYPE_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}
			
			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressMethodDefOrRefToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.METHODDEF_TABLE)
			{
				flag = TokenDecompressor.METHODDEFORREF_METHODDEF;
			}
			else if(type == StreamTable.MEMBERREF_TABLE)
			{
				flag = TokenDecompressor.METHODDEFORREF_MEMBERREF;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}

			row <<= 1;
			if(table_rows[StreamTable.METHODDEF_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX && 
				table_rows[StreamTable.MEMBERREF_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}

			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressHasSemanticsToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.EVENT_TABLE)
			{
				flag = TokenDecompressor.HASSEMANTICS_EVENT;
			}
			else if(type == StreamTable.PROPERTY_TABLE)
			{
				flag = TokenDecompressor.HASSEMANTICS_PROPERTY;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}

			row <<= 1;
			if(table_rows[StreamTable.EVENT_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX && 
				table_rows[StreamTable.PROPERTY_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}

			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressMemberRefParentToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.TYPEREF_TABLE)
			{
				flag = TokenDecompressor.MEMBERREFPARENT_TYPEREF;
			}
			else if(type == StreamTable.MODULEREF_TABLE)
			{
				flag = TokenDecompressor.MEMBERREFPARENT_MODULEREF;
			}
			else if(type == StreamTable.METHODDEF_TABLE)
			{
				flag = TokenDecompressor.MEMBERREFPARENT_METHODDEF;
			}
			else if(type == StreamTable.TYPESPEC_TABLE)
			{
				flag = TokenDecompressor.MEMBERREFPARENT_TYPESPEC;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			
			row <<= 3;
			if(table_rows[StreamTable.TYPEREF_TABLE] < TokenDecompressor.THREE_BIT_TAG_MAX && 
				table_rows[StreamTable.MODULEREF_TABLE] < TokenDecompressor.THREE_BIT_TAG_MAX && 
				table_rows[StreamTable.METHODDEF_TABLE] < TokenDecompressor.THREE_BIT_TAG_MAX && 
				table_rows[StreamTable.TYPESPEC_TABLE] < TokenDecompressor.THREE_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}

			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressResolutionScopeToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.MODULE_TABLE)
			{
				flag = TokenDecompressor.RESOLUTIONSCOPE_MODULE;
			}
			else if(type == StreamTable.MODULEREF_TABLE)
			{
				flag = TokenDecompressor.RESOLUTIONSCOPE_MODULEREF;
			}
			else if(type == StreamTable.ASSEMBLYREF_TABLE)
			{
				flag = TokenDecompressor.RESOLUTIONSCOPE_ASSEMBLYREF;
			}
			else if(type == StreamTable.TYPEREF_TABLE)
			{
				flag = TokenDecompressor.RESOLUTIONSCOPE_TYPEREF;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			
			row <<= 2;
			if(table_rows[StreamTable.MODULE_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.MODULEREF_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.ASSEMBLYREF_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX && 
				table_rows[StreamTable.TYPEREF_TABLE] < TokenDecompressor.TWO_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}

			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressTypeOrMethodDefToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.TYPEDEF_TABLE)
			{
				flag = TokenDecompressor.TYPEORMETHODDEF_TYPEDEF;
			}
			else if(type == StreamTable.METHODDEF_TABLE)
			{
				flag = TokenDecompressor.TYPEORMETHODDEF_METHODDEF;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			
			row <<= 1;
			if(table_rows[StreamTable.TYPEDEF_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX && 
				table_rows[StreamTable.METHODDEF_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}

			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
		
		public static byte [] CompressHasFieldMarshallToken(int[] table_rows,Token token)
		{
			if(table_rows == null)
				throw new ArgumentException("Table Rows cannot be null");
			if(token == null)
				throw new ArgumentException("Token cannot be null");
			byte[] tok = null;
			byte type = token.Table;
			int row = token.Row;
			byte flag = 0;
			if(type == StreamTable.FIELD_TABLE)
			{
				flag = TokenDecompressor.HASFIELDMARSHALL_FIELD;
			}
			else if(type == StreamTable.PARAM_TABLE)
			{
				flag = TokenDecompressor.HASFIELDMARSHALL_PARAM;
			}
			else
			{
				throw new ArgumentException("Error unknown type in uncompressed token: "+type);
			}
			
			row <<= 1;
			if(table_rows[StreamTable.FIELD_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX && 
				table_rows[StreamTable.PARAM_TABLE] < TokenDecompressor.ONE_BIT_TAG_MAX)
			{
				tok = new byte[2];
			}
			else
			{
				tok = new byte[4];
			}

			int i;
			for(i = 0;i < tok.Length;i++)
			{
				tok[i] = Bits.ByteFromInt(i,row);
			}
			tok[0] |= flag;

			return tok;
		}
	}
}
